class GameObject {

    public static allObjects: { [uuid: number]: GameObject } = {};

    private static gameObjectUuidIndex = 1;

    static getGameObject(uuid: number) {
        return this.allObjects[uuid];
    }

    uuid = 0;

    id = "";
    /**
     * 行为组件
     */
    $behaviours: Behaviour[] = [];

    /**
    * 碰撞盒
    */
    collider = null;

    /**
     * 标签
     */
    tag = null;

    /**
     * 标号
     */
    grade = null;

    /**序号 */
    situation=null;

    /**
     * 渲染对象
     */
    renderer = null;

    /**
     *渲染编辑边界
     */
    isEditing = false;

    /**
     * 父节点
     */
    parent = null;

    /**
     * 是否可见
     */
    visible = true;

    /**
     * 是否激活
     */
    $isActive =true;

    /**
     * 子对象
     */
    $children = [];


    onClick: Function = null;

    prefabUrl: string;

    constructor() {
        this.uuid = GameObject.gameObjectUuidIndex++;
        GameObject.allObjects[this.uuid] = this;
        this.tag = new Tag("init",0,0);
        core.$allObject.push(this);
    }

    addBehaviour(newBehaviour: Behaviour) {
        //从behaviour的构造函数中获取对应的名字
        const name = newBehaviour.constructor.name;
        for (const behaviour of this.$behaviours) {
            if (behaviour.constructor.name == name) {
                console.log("该对象已经存在" + name)
                return;
            }
        }
        this.$behaviours.push(newBehaviour);
        newBehaviour.gameObject = this;
        newBehaviour.onAddToGameObject();
    }

    getBehaviour<T extends Behaviour>(behaviourClass: { new(): T }): T {
        const name = behaviourClass.name;
        for (const behaviour of this.$behaviours) {
            if (behaviour.constructor.name == name) {
                return behaviour as T;
            }
        }
        return null;
    }
    //只是调用behaviour中的onDestroy函数，没有将其从数据中移除 
    removeBehaviour(behaviour) {
        behaviour.$isDestroy = true;
    }
    //将behaviour从数据中删除。
    removeBehaviourInData(reBehaviour) {
        let isHaved = false ;
        const name = reBehaviour.constructor.name;
        const behaviours = this.$behaviours;
        for (let behaviour of behaviours) {
            //先类型判断再值判断
            if (behaviour.constructor.name == name) {
                isHaved = true;
                if (behaviour.constructor.name == "Colliderer")
                    this.collider = null;
                if (behaviour.constructor.name == "ImageRenderer" || "RectRenderer" || "TextRenderer")
                    this.renderer = null;
                if (behaviour.constructor.name == "Transform") {
                    console.log("Transform组件不能移除!");
                    return;
                }
                const index = behaviours.indexOf(behaviour);
                console.log(this.id + "已经移除" + behaviour.constructor.name);
                behaviours.splice(index, 1);   //刪除完后要刷新data數據,保證渲染不出問題
                this.removeBehaviour(reBehaviour);
                break;
            }

        }
        if (isHaved == false)
        {
            console.log("对象中不存在"+name+"组件");
        }
    }

    addChild(child) {
        const index = this.$children.indexOf(child);
        if (index == -1) {
            this.$children.push(child);
            child.parent = this;
        }
    }

    removeChild(child) {
        const index = this.$children.indexOf(child);
        if (index >= 0) {
            this.$children.splice(index, 1);
            child.parent = null;
        }
    }

    removeAllChildren() {
        for (let child of this.$children) {
            this.removeChild(child);
        }
    }

    showEditingBox(transform) {
        drawBorder(context, transform)
        console.log(this.id + " iselected")

    }

    setActive(isactive: boolean) {
        if (isactive) {
            this.$isActive = true;
            this.visible = true;
           
        }
        else {
            this.$isActive = false;
            this.visible = false;
 
        }
    }
}


function drawBorder(context, Targettransform) {
    context.beginPath();
    context.strokeStyle = 'yellow';
    context.moveTo(0, 0);
    context.lineTo(0 + Targettransform.width, 0);
    context.lineTo(0 + Targettransform.width, 0 + Targettransform.height);
    context.lineTo(0, 0 + Targettransform.height);
    context.lineTo(0, 0);
    context.stroke();
    context.closePath();
}